﻿#define _CRT_SECURE_NO_WARNINGS
/************************17.字符函数和字符串函数****************************/
#include <stdio.h>

/*******1.字符分类函数******/
//C语⾔中有⼀系列的函数是专⻔做字符分类的，也就是⼀个字符是属于什么类型的字符的。
//这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h
//#include <ctype.h>
//
//int main()
//{
//	/*int r = islower('X');
//	printf("%d ",r);*/
//
//	int ch = 0;
//	ch = getchar();
//	if (islower(ch))
//	{
//		printf("小写字母\n");
//	}
//	else
//	{
//		printf("不是小写字母\n");
//	}
//	return 0;
//}

//写⼀个代码，将字符串中的⼩写字⺟转⼤写，其他字符不变。

//int main()
//{
//	char arr[20] = "I Like C!"; //T LIKE C
//	
//	int i = 0;
//	while (arr[i] != '\0')
//	{
//		//判断arr[i]是否是小写字母 
//		if (islower(arr[i]))
//		{
//			arr[i] -= 32;
//		}
//		i++;
//	}
//	printf("%s\n",arr);
//	return 0;
//}

/*******2. 字符转换函数******/
//C语⾔提供了2个字符转换函数
//int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
//int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

//int main()
//{
//	//int r = tolower('X');
//	int r = toupper('x');
//
//	printf("%c\n",r);
//	putchar(r);
//	return 0;
//}

//int main()
//{
//	char arr[20] = "I Like C!"; //T LIKE C
//	
//	int i = 0;
//	while (arr[i] != '\0')
//	{
//		//判断arr[i]是否是小写字母 
//		if (islower(arr[i]))
//		{
//			arr[i] = toupper(arr[i]);
//		}
//		i++;
//	}
//	printf("%s\n",arr);
//	return 0;
//}

/*******3. strlen 的使⽤和模拟实现******/

//#include <string.h>
//int main()
//{
//	//无符号数减去无符号数，还是无符号数。所以大于0
//	if (strlen("abc") - strlen("abcdef") > 0)
//	{
//		printf(">\n");
//	}
//	else
//	{
//		printf("<=\n");
//	}
//	return 0;
//}

//strlen的递归模拟实现
//#include <assert.h>
//size_t my_strlen(const char* str)
//{
//	assert(str != NULL);
//	if ( *str != '\0')
//	{
//		return 1 + my_strlen(str + 1);
//	}
//	else
//	{
//		return 0;
//	}
//}
//
//int main()
//{
//	//写一个函数求字符串长度 - 不能创建临时变量
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	printf("%zd\n",len);
//	return 0;
//}

/*******4. strcpy 的使⽤和模拟实现******/
//源字符串必须以 '\0' 结束。
//会将源字符串中的 '\0' 拷⻉到⽬标空间。
//⽬标空间必须⾜够⼤，以确保能存放源字符串。
//⽬标空间必须可修改。

//#include <string.h>
//int main()
//{
//	//int arr1[10] = { 1,2,3,4,5 };
//	//int arr2[10] = { 0 };
//	//arr2 = arr1;//err,数组名是地址，地址是一个编号-常量值。
//
//	char arr1[20] = "abcdef";
//	char arr2[20] = { 0 };
//	//arr2 = arr1;//err
//	strcpy(arr2,arr1);
//	printf("%s\n",arr2);
//	return 0;
//}

//int main()
//{
//	char arr1[20] = "abcdef";
//	char* p = "xxxxxxxxxxxx";//常量字符串

//	strcpy(p, arr1);//试图修改常量字符串，就会内存访问出错
//	printf("%s\n", p);//报错
//
//	return 0;
//}

//模拟实现
//#include <assert.h>
//void my_strcpy(char* dest, char* src)
//{
//	while ( *src != '\0')
//	{
//		*dest = *src;
//		src++;
//		dest++;
//	}
//	*dest = *src; //'\0'
//}

//char* my_strcpy(char* dest, const char* src)
//{
//	char* ret = dest;
//	assert(dest && src);//NULL
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//

//int main()
//{
//	char arr1[20] = "abcdef";
//	char arr2[20] = "xxxxxxxxxxxx";
//
//	/*my_strcpy(arr2, arr1);
//	printf("%s\n", arr2);*/
//
//	printf("%s\n", my_strcpy(arr2, arr1));//链式访问
//	return 0;
//}

/*******5. strcat 的使⽤和模拟实现******/
//strcat字符串追加函数
//源字符串必须以 '\0' 结束。
//⽬标字符串中也得有 \0 ，否则没办法知道追加从哪⾥开始。
//⽬标空间必须有⾜够的⼤，能容纳下源字符串的内容。
//⽬标空间必须可修改。

//#include <string.h>
//
//int main()
//{
//	char arr1[20] = "hello ";
//	char arr2[] = "world";
//	strcat(arr1,arr2);
//	printf("%s",arr1);
//	return 0;
//}

//int main()
//{
//	char arr1[20] = "hello ";
//	strcat(arr1, "world");//这样传参，传的是world的首字母地址
//	//1.找到目标字符串的末尾（\0）
//	//2.将源字符串续到后边（拷贝过去）包括\0
//	printf("%s", arr1);
//	return 0;
//}

//#include <assert.h>
////函数返回的是目标空间的起始地址
//
//char* my_strcat(char* dest, const char* src)
//{
//	assert(dest && src);
//	char* ret = dest;
//	//1.找到目标字符串中的(\0),结束标志;
//	while (*dest != '\0');
//	{
//		dest++;
//	}
//	//2.将源字符串拷贝过去
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//
//int main()
//{
//	char arr1[20] = "hello ";
//	my_strcat(arr1, "world");
//	printf("%s\n", arr1);
//	return 0;
//}

/*******6. strcmp 的使⽤和模拟实现******/
//⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩,不是长度。
//a > b，返回>0的数字；a < b,返回<0的数字；a == b ,返回0。
//#include <string.h>
//
//int main()
//{
//	int r = strcmp("abzdef","abq");
//	printf("%d\n",r);
//
//	return 0;
//}

//#include <assert.h>
//int my_strcmp(const char* str1, const char* str2)
//{
//	assert(str1 && str2);
//	while (*str1 == *str2)
//	{
//		if (*str1 == '\0')
//			return 0;
//		str1++;
//		str2++;
//	}
//	if (*str1 > *str2)
//		return 1;
//	else
//		return -1;
//}

//int my_strcmp(const char* str1, const char* str2)
//{
//	assert(str1 && str2);
//	while (*str1 == *str2)
//	{
//		if (*str1 == '\0')
//			return 0;
//		str1++;
//		str2++;
//	}
//	return (*str1 - *str2);
//
//}
//int main()
//{
//	int r = my_strcmp("abcdef","abq");
//	printf("%d\n",r);
//	return 0;
//}

//长度不受限制的字符串函数
/*strcap strcat strcmp*/
//长度受限制的字符串函数//
/*strncap strncat strncmp*/

/*******7.strncpy 的使⽤******/

//int main()
//{
//	char arr1[20] = "xxxxxxxxxxxx";
//	char arr2[20] = "abcdefghi";
//	strncpy(arr1,arr2,6);
//	printf("%s\n",arr1);
//	return 0;
//}

/*******8.strncat 的使⽤******/

//int main()
//{
//	char arr1[20] = "xxx";
//	char arr2[20] = "abcdefghi";
//	strncat(arr1, arr2, 4);//在末尾补'\0'
//	printf("%s\n", arr1);
//	return 0;
//}

/*******9.strncmp 的使⽤******/

//int main()
//{
//	char arr1[20] = "abcdefhi";
//	char arr2[20] = "abcdef";
//	int r = strncmp(arr1, arr2, 6);
//	printf("%d\n",r);
//	return 0; 
//}

/*******10.strstr的使⽤和模拟实现******/
//在一个字符串中查找一个子串,找出第一次出现的位置。
//如果不存在返回空指针。
//#include <string.h>
//
//int main()
//{
//	char arr1[] = "abcdefabcdef";
//	char arr2[] = "def";
//	char * p = strstr(arr1, arr2);
//	if(p == NULL)
//		printf("找不到\n");
//	else
//	    printf("找到了%s\n",p); 
//	return 0;
//} 

//1.在匹配过程中要记录开始匹配位置
//2.找到过程中，如果存在多次匹配的时候，要会回到想要的位置
//#include <assert.h>
//char* my_strstr(const char* str1,const char* str2)
//{
//	assert(str1 && str2);
//	const char* cur = str1;//记录开始匹配位置
//	const char* s1 = NULL;//遍历str1
//	const char* s2 = NULL;//遍历str2
//
//	//特殊情况处理
//	if (*str2 == '\0')//说明子串是一个空字符串
//		return (char*)str1;
//
//	while (*cur)
//	{
//		s1 = cur;
//		s2 = str2;
//		while (*s1 && *s2 && *s1 == *s2)
//		{
//			s1++;
//			s2++;
//		}
//		if (*s2 == '\0')
//		{
//			return (char*)cur;
//		}
//		cur++;
//	}
//	return NULL;//找不到了
//}
//
//int main()
//{
//	char arr1[] = "abbbcdef";
//	char arr2[] = "bbc";
//	char* p = my_strstr(arr1, arr2);
//	if (p == NULL)
//		printf("找不到\n");
//	else
//		printf("找到了%s\n", p);
//	return 0;
//}

/*******11.strtok 函数的使⽤******/
//#include <string.h>
//int main()
//{
//	char arr[] = "zpw@bitedu.net";
//	char buff[20] = { 0 };//可以修改
//	strcpy(buff, arr);
//	const char* p = "@.";
//    
//	//char* r1 = strtok(buff, p);//zpw
//	//printf("%s\n",r1);
//
//	//r1 = strtok(NULL,p);//bitedu
//	//printf("%s\n",r1);
//
//	//r1 = strtok(NULL, p);//net
//	//printf("%s\n", r1);
//
//	char* r = NULL;
//	for (r = strtok(buff, p); r != NULL; r = strtok(NULL, p))
//	{
//		printf("%s\n", r);
//	}
//
//	return 0;
//}

/*******12.strerror 函数的使⽤******/
#include <string.h>
//int main()
//{
//	int i =  0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d: %s\n",i,strerror(i));
//	}
//	return 0;
//}

int main()
{
	 FILE* pf = fopen("unexist.txt", "r");
	 if (pf == NULL)
	 {
		 printf("错误信息: %s\n",strerror(errno));
		 perror("错误信息");//这个函数等于上面printf+strerror
	 }
	return 0;
}

